#!/usr/bin/env python2
# -*- coding: utf-8 -*-

import os
import re
import sys
import time
import datetime

import uuid

from Ump.utils import _exec_pipe

from Ump.common import log

from Ump.objs.db import models
from Ump.objs.session_wrapper import enable_log_and_session, _sw
from Ump.objs.cluster.manager import ClusterManager
from Ump.objs.manager_base import Manager
from Ump.lich.license import LichLicense, LichLicenseParam
from Ump.objs.db.models import  License
from Ump import defs
import  Umpweb



LOG = log.get_log('Ump.objs.license.manager')
cluster_manager = ClusterManager()

license_dir = os.path.dirname(os.path.join(os.path.realpath(Umpweb.__file__)))
license_dir = "%s/static" % license_dir
tar_file = "%s/active.tar" % license_dir

lich_file = os.path.join(license_dir, 'lich_sniffer.info')
message_file = os.path.join(license_dir, 'customer_information.txt')
ump_file = os.path.join(license_dir, 'ump_sniffer.info')

class LicenseManager(Manager):

    def __init__(self):
        super(LicenseManager, self).__init__()
        self.abs_path = os.path.dirname(os.path.realpath(__file__))
        self.lich_license = LichLicense()

    
    def check_license(self, license):
        if not license:
            raise Exception('license not be null')

    @enable_log_and_session(resource='license', event='update_license')
    def activity(self, _logger,  kwargs):

        _logger.update_props(oplog_obj='system')

        self._activity(**kwargs)

    def _activity(self,  **kwargs):
        node_license = kwargs.get('node_license')
        errors = []
        if node_license:
            for hostname, license_id  in node_license.iteritems():
                hostname = os.path.basename(hostname)
                host = models.Host.query.filter_by(hostname=hostname).first() or models.Host.query.filter_by(ip=hostname).first()
		if not host:
                    continue

                
                param = LichLicenseParam(host.ip)
                param.license_id = license_id
                try:
                    self.lich_license.register_fusionnas(param)
                except Exception, e:
                    errors.append("%s register Failed, %s" % (host.ip, e))
                    pass

		
	cluster = models.Cluster.query.first()
	cluster.update({'register_date': self.utils.timenow()})
        self.utils.exception_pass(self.fusionnas_license_sync)

        if errors:
            raise Exception(".".join(errors))

        
    @enable_log_and_session(resource='license', event='make_license')
    def sniffer(self, _logger):
        cmd_list = []
        nodesniffer = {}

        _logger.update_props(oplog_obj='system')

        hosts = _sw.db_hosts()
        if os.path.exists(lich_file):
            rm_cmd = 'rm -rf %s' % lich_file
            _exec_pipe(rm_cmd)

        for host in hosts:
            if not self.is_fusionnas:
                r_cmd = "%s/lich/libexec/lich.license -m sniffer" % (self.lich_home)
            else:
                r_cmd = "/opt/fusionnas/app/bin/uss.license -m sniffer"
            sniffer = self._exec_remote(host.ip, r_cmd, iscode=True)
            nodesniffer[host.name] = sniffer.strip('\n')

        if os.path.exists(ump_file):
            self.rm_file(ump_file)

        l_cmd = 'python %s/manage.py --sniffer > %s' % (defs.UMP_LICENSE_CMD_DIR, ump_file)
        self._exec_local_cmd(l_cmd)

        self.write_to_file(lich_file, nodesniffer)

    @enable_log_and_session(resource='license', event='update_license', disable_oplog=True)
    def create(self, _logger, kwargs):

        _logger.update_props(oplog_obj='system')

        tar_cmd = []
        user_messages = {
            'company': kwargs.get('lic_company_name'),
#            'capacity': kwargs.get('lic_capacity'),
            'contact': kwargs.get('lic_contact'),
            'telephone': kwargs.get('lic_telephone'),
            'email_address': kwargs.get('lic_mail')
        }

        if os.path.exists(message_file):
            self.rm_file(message_file)

        self.write_to_file(message_file, user_messages, flag='message')
        self.sniffer()

        if os.path.exists(tar_file):
            self.rm_file(tar_file)

        tar_cmd = 'tar -C %s -cf %s/active.tar ump_sniffer.info lich_sniffer.info customer_information.txt' %(license_dir, license_dir)
        self._exec_local_cmd(tar_cmd)


        license = models.License(user_messages).save()

        return license

    def rm_file(self, r_file):
        rm_cmd = 'rm -rf %s' % r_file
        self._exec_local_cmd(rm_cmd)


    def _exec_local_cmd(self, l_cmd, cmd=[]):
        if cmd:
            for c in cmd:
                _exec_pipe(c)
        else:
            _exec_pipe(l_cmd)

    def write_to_file(self, file_name, messages, flag=None):

        with open(file_name, 'w+') as f:
            for (k, v) in messages.iteritems():
                if flag == 'message':
                    f.write(k)
                    f.write(":")
                    f.write(v)
                    f.write("\n")
                else:
                    f.write(v)
                    f.write('\n')

    def _host_license_stat(self, cluster):
        for host in cluster.hosts:
            param = LichLicenseParam(host.ip)
            if self.is_ssh_runner:
                param.is_ssh = True

            stat = self.lich_license.list(param)

            register_date = self.lich_license.register_date(param)
            if register_date:
                cluster.update({'register_date':register_date})

            host.update({'license_stat': stat.strip(), 'node_created_at':register_date})
        return cluster

    def _cluster_license_stat(self, cluster):
        invalid_license = ['Node offline', 'No license found', 'License expired', 'Invalid license', 'Excess capacity']
        
        license_stats = []
        for host in cluster.hosts:
            stat = host.license_stat
            license_stat = None

            if stat.startswith('Permanent free license'):
                license_stat = 'permanent' 
            elif stat.startswith('Valid license'):
                license_stat = 'permit' 
            elif stat.startswith('Free license'):
                license_stat = 'free' 

            invalid_stat = [x for x in invalid_license if x in stat]
            if invalid_stat:
                license_stat = 'invalid'

            host.update({'node_register_info':license_stat})
            license_stats.append(license_stat)

        if not license_stats :
            license_stats = ['free']

        license_stat = None
        if 'invalid' in license_stats:
            license_stat = 'invalid'
        elif 'free' in license_stats:
            license_stat = 'free'
        elif 'permanent' in license_stats:
            license_stat = 'permanent'
        else:
            license_stat = 'permit'

        cluster.update({'license_stat': license_stat})
        return cluster

    def _cluster_invalid_date(self, cluster):
        license_expiration_time = None
        for host in cluster.hosts:
            stat = host.license_stat
            if 'license expiration time' not in stat:
                continue

            re_compile = re.compile(r'license expiration time:(.*)')
            license_expiration_times = re_compile.findall(stat)
            if license_expiration_times :
                license_expiration_time = license_expiration_times[0]
                break

        if license_expiration_time:
            invalid_date = datetime.datetime.strptime(license_expiration_time.strip(), '%Y-%m-%d %H:%M:%S') 
            cluster.update({'invalid_date': invalid_date})
        return cluster

    def fusionnas_license_sync(self, is_ssh_runner=False):
        self.is_ssh_runner = is_ssh_runner
        cluster = _sw.db_cluster(1)

        cluster = self._host_license_stat(cluster)

        cluster = self._cluster_license_stat(cluster)

        cluster = self._cluster_invalid_date(cluster)

        return cluster

